﻿using System;
using System.Collections.Generic;
using ApplicationLibrary;
using ApplicationLibrary.CounterManager;
using ApplicationLibrary.DBManager;
using ApplicationLibrary.ExtendedControls;
using ApplicationLibrary.SqlConnector;
using Vintner.Masters.ModuleData;
using Vintner.Sales.ModuleData;
using Vintner.Sales.DataSet;
using Vintner.Sales.Preferences;
using ApplicationLibrary.Preferences;

namespace Vintner.Sales.Reports
{
    public partial class PrintInvoices : ApplicationLibrary.DBManager.ReportForm
    {
        protected bool isDado = false;
        private CounterFormatter formatter = null;
        private DRTaxCode drTaxCode = null;
        private DRDescriptions drTitle = null;
        private DRDescriptions drAppearance = null;
        private DRDescriptions drTransport = null;
        private DRDescriptions drPayment = null;
        private Vintner.Sales.Forms.SaleInvoices.TotalTaxable totals = new Vintner.Sales.Forms.SaleInvoices.TotalTaxable();
        private PrintInvoicesPref myPrintInvoicesPref = null;

        public PrintInvoices()
            : base(Properties.Resources.FN_SalesPrint)
        {
            InitializeComponent();
            //ShowCopies = false;
        }

        protected override void OnBatchExecute(string reportName)
        {
            QueryBuilder qb = new QueryBuilder();
            SqlABCommand scHead = new SqlABCommand(base.providerType);
            scHead.Connection = GlobalInfo.SqlConnection;


            qb.AddSelectAll(VI_SaleInvoices.Name);
            qb.AddFrom(VI_SaleInvoices.Name);

            if (rdbSelectInv.Checked)
            {
                SqlABParameter sFrom = new SqlABParameter("@p3", VI_SaleInvoices.InvoiceNo);
                sFrom.Value = rdrInvFrom.Text;
                scHead.Parameters.Add(sFrom);
                SqlABParameter sTo = new SqlABParameter("@p4", VI_SaleInvoices.InvoiceNo);
                sTo.Value = rdrInvTo.Text;
                scHead.Parameters.Add(sTo);
                qb.AddBetween(VI_SaleInvoices.InvoiceNo, sFrom, sTo);
            }

            if (rdbSelectDate.Checked)
            {
                SqlABParameter sFrom = new SqlABParameter("@p1", VI_SaleInvoices.TransportDate);
                sFrom.Value = ctbFromDate.Today;
                scHead.Parameters.Add(sFrom);
                SqlABParameter sTo = new SqlABParameter("@p2", VI_SaleInvoices.TransportDate);
                sTo.Value = ctbToDate.Today;
                scHead.Parameters.Add(sTo);
                qb.AddBetween(VI_SaleInvoices.TransportDate, sFrom, sTo);
            }

            if (rdbSelectMaster.Checked)
            {
                SqlABParameter sFrom = new SqlABParameter("@p6", VI_SaleInvoices.Customer);
                sFrom.Value = fncCustFrom.Text;
                scHead.Parameters.Add(sFrom);
                SqlABParameter sTo = new SqlABParameter("@p7", VI_SaleInvoices.Customer);
                sTo.Value = fncCustFrom.Text;
                scHead.Parameters.Add(sTo);
                qb.AddBetween(VI_SaleInvoices.Customer, sFrom, sTo);
            }

            qb.AddOrder(VI_SaleInvoices.InvoiceNo);
            qb.AddOrder(VI_SaleInvoices.ReleaseDate);

            scHead.CommandText = qb.Query;

            qb.Clear();
            qb.AddSelectAll(VI_SaleInvoicesDetails.Name);
            qb.AddFrom(VI_SaleInvoicesDetails.Name);
            SqlABParameter sInvoiceNo = new SqlABParameter("@p8", VI_SaleInvoicesDetails.InvoiceNo);
            qb.AddCompare(VI_SaleInvoicesDetails.InvoiceNo, sInvoiceNo);
            qb.AddOrder(VI_SaleInvoicesDetails.Line);

            SqlABCommand scRows = new SqlABCommand(base.providerType);
            scRows.Connection = GlobalInfo.DBaseInfo.dbManager.NewConnection();
            scRows.Parameters.Add(sInvoiceNo);

            scRows.CommandText = qb.Query;
            DSInvoice DsInvoice = new DSInvoice();

            SqlABDataReader drHead = scHead.ExecuteReader();

            //codes.Clear();
            //int cnt = 0;
            while (drHead.Read())
            {
                DSInvoice.HeaderRow dHeader = DsInvoice.Header.NewHeaderRow();
                formatter.Text = drHead.GetValue<string>(VI_SaleInvoices.InvoiceNo);
                dHeader["Prefix"] = formatter.PrefixValue + formatter.PrefixSeparator;
                dHeader["InvoiceProg"] = formatter.CounterNumericValue.ToString("0000000000".Substring(0, formatter.CounterLen));
                dHeader["InvoiceNo"] = formatter.CounterNumericValue;
                dHeader["Suffix"] = formatter.SuffixSeparator + formatter.SuffixValue;
                dHeader[VI_SaleInvoices.InvoiceNo.Name] = drHead.GetValue<string>(VI_SaleInvoices.InvoiceNo);

                dHeader[VI_SaleInvoices.ReleaseDate.Name] = drHead.GetValue<DateTime>(VI_SaleInvoices.ReleaseDate);
                if (string.IsNullOrEmpty(drHead.GetValue<string>(VI_SaleInvoices.Title)))
                    dHeader[VI_SaleInvoices.Title.Name] = "Spett.";
                else
                {
                    if (drTitle.Find(drHead.GetValue<string>(VI_SaleInvoices.Title)))
                        dHeader[VI_SaleInvoices.Title.Name] = drTitle.GetValue<string>(VI_Descriptions.Description);
                    else
                        dHeader[VI_SaleInvoices.Title.Name] = "Spett.";
                }

                string trimmedDesc = drHead.GetValue<string>(VI_SaleInvoices.Description).TrimEnd(new char[] { '\r', '\n', '\t', ' ' });
                trimmedDesc = string.Concat(trimmedDesc, '\n', drHead.GetValue<string>(VI_SaleInvoices.Address), "\n");
                dHeader[VI_SaleInvoices.Description.Name] = string.Concat(trimmedDesc, drHead.GetValue<string>(VI_SaleInvoices.ZipCode), " ", drHead.GetValue<string>(VI_SaleInvoices.City), " ", drHead.GetValue<string>(VI_SaleInvoices.County));

                dHeader[VI_SaleInvoices.FiscalCode.Name] = drHead.GetValue<string>(VI_SaleInvoices.FiscalCode);
                dHeader[VI_SaleInvoices.TaxNo.Name] = drHead.GetValue<string>(VI_SaleInvoices.TaxNo);
                drPayment.Find(drHead.GetValue<string>(VI_SaleInvoices.Payment));
                dHeader[VI_SaleInvoices.Payment.Name] = drPayment.GetValue<string>(VI_Descriptions.Description);

                dHeader[VI_SaleInvoices.LitresNo.Name] = drHead.GetValue<double>(VI_SaleInvoices.LitresNo);
                dHeader[VI_SaleInvoices.PackagesNo.Name] = drHead.GetValue<int>(VI_SaleInvoices.PackagesNo);
                dHeader[VI_SaleInvoices.DestGoods.Name] = drHead.GetValue<string>(VI_SaleInvoices.DestGoods);

                dHeader[VI_SaleInvoices.Appearance.Name] = DecodeAppearance(drHead.GetValue<string>(VI_SaleInvoices.Appearance));

                drTransport.Find(drHead.GetValue<string>(VI_SaleInvoices.Transport));
                dHeader[VI_SaleInvoices.Transport.Name] = drTransport.GetValue<string>(VI_Descriptions.Description);

                dHeader[VI_SaleInvoices.TransportDate.Name] = drHead.GetValue<DateTime>(VI_SaleInvoices.TransportDate).ToString("dd/MM/yy HH:mm");


                DsInvoice.Header.AddHeaderRow(dHeader);

                sInvoiceNo.Value = drHead.GetValue<string>(VI_SaleInvoices.InvoiceNo);
                SqlABDataReader drRows = scRows.ExecuteReader();
                totals.Clear();

                while (drRows.Read())
                {
                    DSInvoice.RowRow dRow = DsInvoice.Row.NewRowRow();

                    dRow[VI_SaleInvoicesDetails.InvoiceNo.Name] = drHead.GetValue<string>(VI_SaleInvoices.InvoiceNo);
                    dRow[VI_SaleInvoicesDetails.Line.Name] = drRows.GetValue<int>(VI_SaleInvoicesDetails.Line);
                    dRow[VI_SaleInvoicesDetails.Item.Name] = drRows.GetValue<string>(VI_SaleInvoicesDetails.Item);
                    dRow[VI_SaleInvoicesDetails.Description.Name] = drRows.GetValue<string>(VI_SaleInvoicesDetails.Description);
                    dRow[VI_SaleInvoicesDetails.Price.Name] = drRows.GetValue<double>(VI_SaleInvoicesDetails.Price);
                    dRow[VI_SaleInvoicesDetails.Quantity.Name] = drRows.GetValue<double>(VI_SaleInvoicesDetails.Quantity);
                    drTaxCode.Find(drRows.GetValue<string>(VI_SaleInvoicesDetails.TaxCode));
                    dRow[VI_SaleInvoicesDetails.TaxCode.Name] = drTaxCode.GetValue<string>(VI_TaxCode.Description);
                    DsInvoice.Row.AddRowRow(dRow);

                    double totalAmount = drRows.GetValue<double>(VI_SaleInvoicesDetails.Quantity) * drRows.GetValue<double>(VI_SaleInvoicesDetails.Price);

                    totals.Add(drRows.GetValue<string>(VI_SaleInvoicesDetails.TaxCode),
                                drTaxCode.GetValue<string>(VI_TaxCode.Description),
                                totalAmount,
                                totalAmount * drTaxCode.GetValue<double>(VI_TaxCode.Percent) / 100);
                }

                dHeader["Total"] = totals.totAmount + totals.totTax;
                drRows.Close();


                foreach (KeyValuePair<string, Vintner.Sales.Forms.SaleInvoices.TaxableData> kvp in totals)
                {
                    DSInvoice.TaxRow dTax = DsInvoice.Tax.NewTaxRow();

                    dTax["SaleNo"] = drHead.GetValue<string>(VI_SaleInvoices.InvoiceNo);
                    dTax["Amount"] = kvp.Value.Amount;
                    dTax["TaxCode"] = kvp.Value.Desc;
                    dTax["TaxAmount"] = kvp.Value.Tax;
                    DsInvoice.Tax.AddTaxRow(dTax);
                }
            }
            drHead.Close();
            GlobalInfo.DBaseInfo.dbManager.CloseConnection(scRows.Connection);

            SetParameterValue("IsDado", isDado);
            ShowReport(new PrintSales(), DsInvoice);
        }

        protected override void OnDisableControlsForRun()
        {
            ctbFromDate.Enabled = rdbSelectDate.Checked;
            ctbToDate.Enabled = rdbSelectDate.Checked;

            fncCustFrom.Enabled = rdbSelectMaster.Checked;
            fncCustTo.Enabled = rdbSelectMaster.Checked;

            rdrInvFrom.Enabled = rdbSelectInv.Checked;
            rdrInvTo.Enabled = rdbSelectInv.Checked;
        }

        protected override void OnAttachData()
        {
            ctbFromDate.Today = GlobalInfo.CurrentDate;
            ctbToDate.Today = GlobalInfo.CurrentDate;
            fncCustFrom.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_Customers), GlobalInfo.CurrentDate);
            fncCustTo.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_Customers), GlobalInfo.CurrentDate);
            fncCustFrom.RadarForm = new RadarCustomerForm();
            fncCustTo.RadarForm = new RadarCustomerForm();
            fncCustFrom.DescriptionControl = txtCustFrom;
            fncCustTo.DescriptionControl = txtCustTo;
            formatter = new CounterFormatter();
            drTaxCode = new DRTaxCode();
            drTitle = new DRDescriptions(DescriptionType.E_Title);
            drAppearance = new DRDescriptions(DescriptionType.E_Appearance);
            drTransport = new DRDescriptions(DescriptionType.E_Transport);
            drPayment = new DRDescriptions(DescriptionType.E_Payment);
            myPrintInvoicesPref = new PreferencesManager<PrintInvoicesPref>(this.Name, null).ReadPreference();

            if (isDado)
            {
                rdrInvFrom.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_Dado), GlobalInfo.CurrentDate);
                rdrInvTo.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_Dado), GlobalInfo.CurrentDate);
                formatter.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_Dado), GlobalInfo.CurrentDate);
            }
            else
            {
                rdrInvFrom.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_SalesInvoice), GlobalInfo.CurrentDate);
                rdrInvTo.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_SalesInvoice), GlobalInfo.CurrentDate);
                formatter.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_SalesInvoice), GlobalInfo.CurrentDate);
            }

            rdrInvFrom.RadarForm = new RadarSaleInvoices() {isDado=this.isDado};
            rdrInvTo.RadarForm = new RadarSaleInvoices() {isDado=this.isDado};

            base.OnAttachData();
        }

        protected override void OnBindData()
        {
            BindControl(rdrInvFrom);
            BindControl(rdrInvTo);
        }

        protected override void OnAddPreferenceButton(ApplicationLibrary.Preferences.PreferenceForm prefForm)
        {
            prefForm.AddPanel(new PrintInvoicesPreferencePanel(this.Name));
            base.OnAddPreferenceButton(prefForm);
        }

        protected override void OnDoubleClickColumn(string column, string value)
        {
            //formatter.InvertedSuffixPrefix = true;
            //formatter.Text = value;
            //formatter.InvertedSuffixPrefix = false;
            //Sales.Forms.SalesInvoice frm = (Sales.Forms.SalesInvoice)GlobalInfo.OpenForm("Plumber.Plumber.Sales.Forms.SalesInvoice", false);
            //frm.FindRecord(new RadarSaleInvoicesParam(formatter.ToString()));
        }

        private void rdbRangeDate_CheckedChanged(object sender, EventArgs e)
        {
            ctbFromDate.Enabled = rdbSelectDate.Checked;
            ctbToDate.Enabled = rdbSelectDate.Checked;
        }

        private void rdbRangeMaster_CheckedChanged(object sender, EventArgs e)
        {
            fncCustFrom.Enabled = rdbSelectMaster.Checked;
            fncCustTo.Enabled = rdbSelectMaster.Checked;
        }

        private void rdrFrom_Validated(object sender, EventArgs e)
        {
            if (fncCustTo.Text.CompareTo(fncCustFrom.Text) < 0)
                fncCustTo.Text = fncCustFrom.Text;
        }

        private void rdrTo_Validated(object sender, EventArgs e)
        {
            if (fncCustTo.Text.CompareTo(fncCustFrom.Text) < 0)
                fncCustFrom.Text = fncCustTo.Text;
        }

        private void ctbFromDate_Validated(object sender, EventArgs e)
        {
            ctbToDate.Today = ctbFromDate.Today;
        }

        private void ctbToDate_Validated(object sender, EventArgs e)
        {
        }


        protected override EmailArgs SendEmail()
        {
            EmailArgs ea = new EmailArgs();
            ea.Subject = "Fatture";
            ea.Attachment = ExportToPdf("Fatture");
            return ea;
        }

        private void rdbSelectInv_CheckedChanged(object sender, EventArgs e)
        {
            rdrInvFrom.Enabled = rdbSelectInv.Checked;
            rdrInvTo.Enabled = rdbSelectInv.Checked;
        }

        private void rdrInvFrom_Validated(object sender, EventArgs e)
        {
            if (rdrInvTo.Text.CompareTo(rdrInvFrom.Text) < 0)
                rdrInvTo.Text = rdrInvFrom.Text;
        }

        private void rdrInvTo_Validated(object sender, EventArgs e)
        {
            if (rdrInvTo.Text.CompareTo(rdrInvFrom.Text) < 0)
                rdrInvFrom.Text = rdrInvTo.Text;
        }

        private string DecodeAppearance(string codes)
        {
            string result = string.Empty;

            foreach (string code in codes.Split(new char[] { ',' }))
            {
                if (drAppearance.Find(code))
                {
                    drAppearance.GetValue<string>(VI_Descriptions.Description);
                    result = result.SeparConcat(drAppearance.GetValue<string>(VI_Descriptions.Description), " ");
                }
            }
            return result;
        }
    }

    public class DadoPrintInvoices : PrintInvoices
    {
        public DadoPrintInvoices()
            : base()
        {
            isDado = true;
            Text = "Dado Stampa Fattura";
        }    
    }
}